package com.jieyun.core.component.shiro;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;

import com.jieyun.core.constant.Constant;
import com.jieyun.core.utils.SpringUtils;
import com.jieyun.rbac.constant.RBACConstant;
import com.jieyun.rbac.dto.User;
import com.jieyun.rbac.mapper.SysDeptMapper;
import com.jieyun.rbac.mapper.SysUserMapper;
import com.jieyun.rbac.po.SysDept;
import com.jieyun.rbac.po.SysUser;

/**
 * 自定义的shiro Realm
 * 
 * @author trek
 *
 */
public class ShiroRealm extends AuthorizingRealm {

	/**
	 * 完成认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken utoken = (UsernamePasswordToken) token;
		String username = utoken.getUsername();
		String password = new String(utoken.getPassword());
		// 查询用户
		SysUser user = getSysUserMapper().selectOne(SysUser.builder().username(username).build());
		if (user == null) {
			throw new UnknownAccountException();
		}

		// 比较密码
		if (!StringUtils.equals(password, user.getPassword())) {
			throw new IncorrectCredentialsException();
		}

		// 判断状态
		if (user.getStatus() == RBACConstant.UserStatus.lock) {
			throw new LockedAccountException();
		}

		// 现在认为用户的账号和密码是没有问题的了
		user.setPassword(null);
		SysDept dept = getSysDeptMapper().selectOne(SysDept.builder().id(user.getId()).build());

		User sessionUser = User.builder().sysUser(user).sysDept(dept).build();

		Session session = SecurityUtils.getSubject().getSession();

		session.setAttribute(Constant.SESSION_USER, sessionUser);

		return new SimpleAuthenticationInfo(sessionUser, password.toCharArray(), this.getClass().getSimpleName());
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		return null;
	}

	/**
	 * 获取用户mapper
	 * 
	 * @return
	 */
	private SysUserMapper getSysUserMapper() {
		return SpringUtils.getBean(SysUserMapper.class);
	}

	/**
	 * 获取组织信息
	 * 
	 * @return
	 */
	private SysDeptMapper getSysDeptMapper() {
		return SpringUtils.getBean(SysDeptMapper.class);
	}

}
